﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace team33_ass3
{
    /// <summary>
    /// A node for A* Algorithm.
    /// </summary>
    class AStarNode : IComparable<AStarNode>, IEquatable<AStarNode>
    {
        public MapBlock block;
        public AStarNode parent;
        
        
        public int F; // Total cost from this block to its parents
        public int G; // Movement cost, probs won't be used
        public int H; // Estimated movement cost to move to the end block

        /// <summary>
        /// Does nothing, just for placeholder.
        /// </summary>
        public AStarNode()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="block"></param>
        /// <param name="parent"></param>
        /// <param name="f"></param>
        /// <param name="h"></param>
        public AStarNode(MapBlock block, AStarNode parent, int f, int h)
        {
            this.block = block;
            this.parent = parent;
            this.F = f;
            this.H = h;
            this.G = 10;
        }

        public AStarNode(MapBlock block, AStarNode parent)
        {
            this.block = block;
            this.parent = parent;
            this.G = 10;
        }

        public AStarNode(MapBlock block)
        {
            this.block = block;
            this.G = 10;
        }

        /// <summary>
        /// Compares the current instance with another AStarNode and returns an integer that indicates whether the current instance preces, follows
        /// or occurs in the same position in the sort order as the other object.
        /// 
        /// Value               Meaning
        /// Less than zero      This instance precedes obj in the sort order.
        /// Zero                This instance occurs in the same position in the sort order as obj.
        /// Greater than zero   This instance follows obj in the sort order.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(AStarNode other)
        {
            if (this.H == other.H)
                return 0;
            else if (this.H > other.H)
                return -1;
            else
                return 1;
        }

        public bool Equals(AStarNode other)
        {
            if (other.block == null)
                return false;

            return this.block.Equals(other.block);
        }

        public static bool operator ==(AStarNode lhs, AStarNode rhs)
        {
            if (rhs.block == null || lhs.block == null)
                return false;

            return lhs.block.Equals(rhs.block);
        }

        public static bool operator !=(AStarNode lhs, AStarNode rhs)
        {
            if (rhs.block == null || lhs.block == null)
                return false;

            return !lhs.block.Equals(rhs.block);
        }

        public static bool operator ==(AStarNode lhs, MapBlock rhs)
        {
            if (rhs == null || lhs.block == null)
                return false;

            return lhs.block.Equals(rhs);
        }

        public static bool operator !=(AStarNode lhs, MapBlock rhs)
        {
            if (rhs == null || lhs.block == null)
                return false;

            return !lhs.block.Equals(rhs);
        }
    }
}
